package com.ybg.block.core.fabric;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ybg.block.core.dbapi.entity.FabricCa;
import com.ybg.block.core.dbapi.entity.FabricOrg;
import com.ybg.block.core.dbapi.entity.FabricPeer;
import com.ybg.block.core.dbapi.service.FabricAppService;
import com.ybg.block.core.dbapi.service.FabricBlockService;
import com.ybg.block.core.dbapi.service.FabricCaService;
import com.ybg.block.core.dbapi.service.FabricChaincodeService;
import com.ybg.block.core.dbapi.service.FabricChannelService;
import com.ybg.block.core.dbapi.service.FabricOrgService;
import com.ybg.block.core.dbapi.service.FabricPeerService;
import com.ybg.block.core.fabric.datamapper.FabricPeerDataMapper;
import com.ybg.share.core.fabric.FabricPeerRemoteApi;
import com.ybg.share.core.fabric.dto.FabricPeerEditDTO;
import com.ybg.share.core.fabric.dto.FabricPeerQueryDTO;
import com.ybg.share.core.fabric.vo.FabricPeerVO;
import com.ybg.framework.vo.R;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;

import java.time.LocalDateTime;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service(version = "${dubbo.provider.version}", timeout = 120000, cache = "false")
public class FabricPeerRemoteApiImpl implements FabricPeerRemoteApi {
    @Autowired
    private FabricPeerService fabricPeerService;
    @Autowired
    private FabricOrgService fabricOrgService;
    @Autowired
    private FabricCaService fabricCaService;
    @Autowired
    private FabricChannelService fabricChannelService;
    @Autowired
    private FabricBlockService fabricBlockService;
    @Autowired
    private FabricChaincodeService fabricChaincodeService;
    @Autowired
    private FabricAppService fabricAppService;

    @Override
    public R<?> editPeer(FabricPeerEditDTO dto) {
        FabricOrg fabricOrg = null;
        FabricPeer updatePeer = null;
        if (dto.getId() != null) {
            dto.setOrgId(null);
        }
        if (dto.getId() == null && dto.getOrgId() == null) {
            return R.fail("组织ID不能为空");
        }
        if (StrUtil.isBlank(dto.getName())) {
            return R.fail("节点名称不能为空");
        }
        if (StrUtil.isBlank(dto.getLocation())) {
            return R.fail("节点访问地址不能为空");
        }
        if (StrUtil.isBlank(dto.getEventHubLocation())) {
            return R.fail("事件路径不能为空");
        }
        if (dto.getOrgId() != null) {
            fabricOrg = fabricOrgService.getById(dto.getId());
            if (fabricOrg == null) {
                return R.fail("组织不存在");
            }
        }
        if (dto.getId() != null) {
            updatePeer = fabricPeerService.getById(dto.getId());
            if (updatePeer == null) {
                return R.fail("数据不存在");
            }
            fabricOrg = fabricOrgService.getById(updatePeer.getOrgId());
        }
        if (updatePeer == null) {
            updatePeer = new FabricPeer();
        }

        updatePeer.setName(dto.getName());
        updatePeer.setLocation(dto.getLocation());
        updatePeer.setEventHubLocation(dto.getEventHubLocation());
        updatePeer.setOrgId(dto.getOrgId());
        updatePeer.setServerCrtPath(dto.getServerCrtPath());
        updatePeer.setClientCertPath(dto.getClientCertPath());
        updatePeer.setClientKeyPath(dto.getClientKeyPath());
        updatePeer.setCreateTime(LocalDateTime.now());
        updatePeer.setLeagueId(fabricOrg.getLeagueId());
        updatePeer.setOrgName(fabricOrg.getMspId());
        updatePeer.setLeagueName(fabricOrg.getLeagueName());
        //updatePeer.setChannelCount(0);
        fabricPeerService.saveOrUpdate(updatePeer);
        return R.success();
    }

    @Override
    public R<?> deletePeer(Long id) {
        FabricPeer fabricPeer = fabricPeerService.getById(id);
        if (fabricPeer == null) {
            return R.fail("数据不存在");
        }
        fabricPeerService.removeById(id);
        Map<String, Object> condition = new LinkedHashMap<>(1);
        condition.put(FabricCa.PEER_ID, id);
        fabricCaService.removeByMap(condition);
        fabricChannelService.removeByMap(condition);
        fabricBlockService.removeByMap(condition);
        fabricChaincodeService.removeByMap(condition);
        fabricAppService.removeByMap(condition);
        return R.success();
    }

    @Override
    public R<FabricPeerVO> getPeer(Long id) {
        FabricPeer fabricPeer = fabricPeerService.getById(id);
        return R.success(FabricPeerDataMapper.INSTANCE.toVO(fabricPeer));
    }

    @Override
    public R<List<FabricPeerVO>> query(FabricPeerQueryDTO dto) {
        QueryWrapper<FabricPeer> wrapper = new QueryWrapper<>();
        wrapper.eq(dto.getId() != null, FabricPeer.ID, dto.getId());
        wrapper.eq(dto.getLeagueId() != null, FabricPeer.LEAGUE_ID, dto.getLeagueId());
        wrapper.eq(dto.getOrgId() != null, FabricPeer.ORG_ID, dto.getOrgId());
        List<FabricPeer> fabricPeers = fabricPeerService.list(wrapper);
        return R.success(FabricPeerDataMapper.INSTANCE.toVOList(fabricPeers));
    }


}
